package com.iwomy.secureplat.platform.transmission;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.iwomy.secureplat.common.core.util.SpringContextHolder;
import com.iwomy.secureplat.common.data.tenant.TenantBroker;
import com.iwomy.secureplat.platform.entity.BasicDeviceEntity;
import com.iwomy.secureplat.platform.service.BasicDeviceService;
import com.iwomy.secureplat.platform.transmission.entity.SensorTransmissionData;
import com.iwomy.secureplat.platform.transmission.parse.ParseData;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;


public class DataServerHandler extends ChannelInboundHandlerAdapter {
	private static Logger log = LoggerFactory.getLogger(DataServerHandler.class);
	private ParseData parseData;

	private Map<String, BasicDeviceEntity> map = new HashMap();

	public DataServerHandler(ParseData parseData) {
		this.parseData = parseData;
	}

	/**
	 * 当我们通道进行激活的时候 触发的监听方法
	 */
	@Override
	public void channelActive(ChannelHandlerContext ctx) {
		log.debug(parseData.getDrcProInfo().getParseDataName() + "--------通道激活------------");
	}

	@Override
	public void channelUnregistered(ChannelHandlerContext ctx) {
		log.info("注销");
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) {
		log.info("--------设备断开------------");
		String channelId = ctx.channel().id().toString();
		BasicDeviceEntity basicDeviceEntity = map.remove(channelId);
		if (ObjectUtil.isNull(basicDeviceEntity)) return;
		LambdaUpdateWrapper<BasicDeviceEntity> updateWrapper = Wrappers.lambdaUpdate(BasicDeviceEntity.class)
				.set(BasicDeviceEntity::getOnline, 10).eq(BasicDeviceEntity::getId, basicDeviceEntity.getId());
		BasicDeviceService basicDeviceService = SpringContextHolder.getBean(BasicDeviceService.class);
		basicDeviceService.update(updateWrapper);
		log.info(basicDeviceEntity.getImei() + "--------设备断开------------");

//		RedisClient redisClient = SpringContextHolder.getBean(RedisClient.class);
//		String key = RedisConstants.REDIS_KEY_DEVICE_ONLINE + basicDeviceEntity.getImei();
//		redisClient.del(key);
	}

	@Override
	public void channelRegistered(ChannelHandlerContext ctx) {
		log.debug("--------通道注册------------");
	}


	/**
	 * 当我们的通道里有数据进行读取的时候 触发的监听方法
	 *
	 * @param ctx NETTY服务上下文
	 * @param msg 实际的传输数据
	 * @throws Exception
	 */
	@Override

	public void channelRead(ChannelHandlerContext ctx, Object msg) {
		new Thread(() -> {
			if (msg instanceof byte[]) {
				byte[] bytes = (byte[]) msg;
				//解析 ,需要判定是否是心跳包
				//TODO 这里是否可以用 ThreadLocal来存储变量信息

				BasicDeviceEntity device = new BasicDeviceEntity();
				SensorTransmissionData parse = parseData.parse(bytes, device);
				if (ObjectUtil.isNull(parse) || StrUtil.isEmpty(device.getImei())) {
//				log.info(parseData.getDrcProInfo().getParseDataName() + ",接收数据解析失败");
					return;
				}
				String channelId = ctx.channel().id().toString();
				map.put(channelId, device);
//			//存储
//			if (!parseData.save()) {
//				log.error(parseData.getDrcProInfo().getParseDataName() + ",数据存储失败");
//				return;
//			}
				TenantBroker.runAs(device.getTenantId(), id -> {
					if (!parseData.alarm(device, parse)) {
						log.error(parseData.getDrcProInfo().getParseDataName() + ",数据存储到TXT失败");
						return;
					}
					return;
				});
			}
		}).start();
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		log.info(parseData.getDrcProInfo().getParseDataName() + "--------数据读取完毕----------");
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
			throws Exception {
		log.error(parseData.getDrcProInfo().getParseDataName() + "--------数据读异常----------: ");
		cause.printStackTrace();
		ctx.close();
	}
}